package cn.devzyh.oms.coms.flow.context;

import cn.devzyh.oms.common.core.util.R;
import cn.devzyh.oms.coms.flow.executor.FlowNode;
import lombok.Data;

import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

/**
 * 工作流执行上下文
 */
@Data
public class FlowContext {

	/**
	 * 流程ID
	 */
	Long flowId;

	/**
	 * 流程请求参数
	 */
	Map<String, Object> params;

	/**
	 * 流程执行缓存
	 */
	Map<String, Object> cache;

	/**
	 * 测试流程
	 */
	boolean test;

	/**
	 * 当前节点ID
	 */
	Long currentNodeId;

	/**
	 * 输出数据
	 */
	Map<String, Object> output;

	/**
	 * 回滚节点栈
	 */
	Stack<FlowNode> rollbackStack;

	/**
	 * 主要缓存键
	 */
	private static final String MAIN_CACHE = "main";

	public FlowContext(Long flowId) {
		this.flowId = flowId;
		this.cache = new HashMap<>();
		this.output = new HashMap<>();
		this.rollbackStack = new Stack<>();
	}

	/**
	 * 记录成功执行节点
	 *
	 * @param fn
	 */
	public void processed(FlowNode fn) {
		this.rollbackStack.push(fn);
	}

	/**
	 * 流程回滚
	 *
	 * @return 是否回滚成功
	 */
	public boolean rollback() {
		boolean success = true;
		R res;

		while (!this.rollbackStack.empty()) {
			FlowNode fn = this.rollbackStack.pop();
			res = fn.rollback(this);
			if (res.failure()) {
				success = false;
			}
		}

		return success;
	}

	/**
	 * 添加节点结果
	 *
	 * @param key
	 * @param value
	 */
	public void addResult(String key, Object value) {
		this.output.put(key, value);
	}

	/**
	 * 获取请求参数
	 *
	 * @param key
	 */
	public Object getParam(String key) {
		return this.params.get(key);
	}

	/**
	 * 设置关键缓存
	 */
	public void setMainCache(Object value) {
		this.cache.put(MAIN_CACHE, value);
	}

	/**
	 * 获取关键缓存
	 */
	public Object getMainCache() {
		return this.cache.get(MAIN_CACHE);
	}

}
